From: Marek Chalupa Date: Thu, 31 Mar 2016 12:26:06 +0000 (+0200) Subject: dnd: Cancel the animation on drag actor destruction X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~875 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=1883df2927b9d088bf31f6d02ddbffac2de319f0;p=gnome-shell.git dnd: Cancel the animation on drag actor destruction If the drag actor is destroyed before the animation callback is called, the callback is never called and we're sticked with dnd grabing the events after we dropped the target. https://bugzilla.gnome.org/show_bug.cgi?id=757676 --- diff --git a/js/ui/dnd.js b/js/ui/dnd.js index c7140a1c2..e749dd9a8 100644 --- a/js/ui/dnd.js +++ b/js/ui/dnd.js @@ -571,20 +571,13 @@ const _Draggable = new Lang.Class({ return; } - this._animationInProgress = true; - // No target, so snap back - Tweener.addTween(this._dragActor, - { x: snapBackX, - y: snapBackY, - scale_x: snapBackScale, - scale_y: snapBackScale, - opacity: this._dragOrigOpacity, - time: SNAP_BACK_ANIMATION_TIME, - transition: 'easeOutQuad', - onComplete: this._onAnimationComplete, - onCompleteScope: this, - onCompleteParams: [this._dragActor, eventTime] - }); + this._animateDragEnd(eventTime, + { x: snapBackX, + y: snapBackY, + scale_x: snapBackScale, + scale_y: snapBackScale, + time: SNAP_BACK_ANIMATION_TIME, + }); }, _restoreDragActor: function(eventTime) { @@ -596,18 +589,44 @@ const _Draggable = new Lang.Class({ this._dragActor.set_scale(restoreScale, restoreScale); this._dragActor.opacity = 0; + this._animateDragEnd(eventTime, + { time: REVERT_ANIMATION_TIME }); + }, + + _animateDragEnd: function (eventTime, params) { this._animationInProgress = true; - Tweener.addTween(this._dragActor, - { opacity: this._dragOrigOpacity, - time: REVERT_ANIMATION_TIME, - transition: 'easeOutQuad', - onComplete: this._onAnimationComplete, - onCompleteScope: this, - onCompleteParams: [this._dragActor, eventTime] - }); + + // finish animation if the actor gets destroyed + // during it + this._dragActorDestroyId = + this._dragActor.connect('destroy', + Lang.bind(this, this._finishAnimation)); + + params['opacity'] = this._dragOrigOpacity; + params['transition'] = 'easeOutQuad'; + params['onComplete'] = this._onAnimationComplete; + params['onCompleteScope'] = this; + params['onCompleteParams'] = [this._dragActor, eventTime]; + + // start the animation + Tweener.addTween(this._dragActor, params) + }, + + _finishAnimation : function () { + if (!this._animationInProgress) + return + + this._animationInProgress = false; + if (!this._buttonDown) + this._dragComplete(); + + global.screen.set_cursor(Meta.Cursor.DEFAULT); }, _onAnimationComplete : function (dragActor, eventTime) { + dragActor.disconnect(this._dragActorDestroyId); + this._dragActorDestroyId = 0; + if (this._dragOrigParent) { Main.uiGroup.remove_child(this._dragActor); this._dragOrigParent.add_actor(this._dragActor); @@ -616,12 +635,9 @@ const _Draggable = new Lang.Class({ } else { dragActor.destroy(); } - global.screen.set_cursor(Meta.Cursor.DEFAULT); - this.emit('drag-end', eventTime, false); - this._animationInProgress = false; - if (!this._buttonDown) - this._dragComplete(); + this.emit('drag-end', eventTime, false); + this._finishAnimation(); }, _dragComplete: function() {